
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Spring AI + SpringBoot搭建智能应用 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>Spring AI + SpringBoot搭建智能应用 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Spring AI项目的核心定位是什么，它遵循了Spring生态的哪一贯理念？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring AI是Spring团队于2023年推出的开源项目，旨在为Java开发者提供简单易用的AI集成能力。它遵循Spring一贯的“约定优于配置”理念，让开发者能够专注于业务逻辑而非底层实现。</div>
          </div>
          <div class="card-source">来源: 1. Spring AI生态概览 / Spring AI项目定位与发展历程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">文档中列举了Spring AI的哪些核心模块？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档中列举的核心模块包括：spring-ai-core (核心抽象和接口), spring-ai-openai (OpenAI集成), spring-ai-bedrock (AWS Bedrock集成), 和 spring-ai-vertex (Google Vertex AI集成)。</div>
          </div>
          <div class="card-source">来源: 1. Spring AI生态概览 / Spring AI核心模块与功能地图</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在Spring AI中，如何使用PromptTemplate来动态创建提示词？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以使用一个包含占位符（如 {framework}）的字符串来创建PromptTemplate实例。然后，通过一个Map对象提供占位符对应的具体值，调用`promptTemplate.create(params)`方法即可生成一个包含动态内容的Prompt对象。</div>
          </div>
          <div class="card-source">来源: 4. 提示词工程实战 / PromptTemplate使用方法</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如何在Spring AI中调整模型的生成参数，例如温度（temperature）和最大令牌数（maxTokens）？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过创建一个ChatOptions对象可以调整模型参数。例如，使用`ChatOptions.builder().temperature(0.7f).maxTokens(500).build()`来构建一个包含自定义参数的配置，然后将其与消息一起封装在Prompt对象中。</div>
          </div>
          <div class="card-source">来源: 3. 模型接入与管理 / 模型参数调优技巧</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在Spring AI中，如何实现对话上下文管理以支持多轮对话？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过维护一个`List<Message>`作为对话历史。这个列表包含了之前的`SystemMessage`（系统角色）、`UserMessage`（用户提问）和`AssistantMessage`（模型回答）。当用户提出新问题时，将其作为新的`UserMessage`添加到历史列表中，然后将整个列表作为新的Prompt提交给模型。</div>
          </div>
          <div class="card-source">来源: 4. 提示词工程实战 / 变量注入与上下文管理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">架构</div>
          <div class="card-question">文档中描述的RAG（检索增强生成）架构包含哪四个核心流程？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">架构</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">RAG架构的四个核心流程是：1. 将文档进行嵌入计算并存储到向量数据库。2. 将用户的查询也转换为嵌入向量。3. 在向量数据库中进行相似度搜索，找到与查询最相关的文档。4. 将相关文档内容与用户的原始查询一起作为上下文，发送给大语言模型（LLM）生成最终答案。</div>
          </div>
          <div class="card-source">来源: 6. RAG应用构建 / RAG架构设计</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在构建RAG应用时，检索到相关文档后，如何构造最终发送给LLM的提示词（Prompt）？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">将检索到的多个相关文档的内容拼接成一个大的上下文（context）字符串。然后，将这个上下文和用户的原始问题组合成一个新的提示词，通常格式为：“基于以下信息回答问题: [上下文信息] 问题: [用户原始问题]”。</div>
          </div>
          <div class="card-source">来源: 6. RAG应用构建 / 检索增强生成核心代码</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">为了对AI服务的调用进行性能优化和成本控制，文档中推荐了什么方法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档推荐使用缓存策略。通过为Spring Boot应用开启缓存（@EnableCaching），并在调用AI服务的方法上添加@Cacheable注解，可以缓存对相同提示词（Prompt）的响应结果，避免重复调用API，从而提高性能并节约成本。</div>
          </div>
          <div class="card-source">来源: 7. 实用案例 / 性能优化与成本控制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在Spring AI中，如何将系统级的指令（例如角色设定）与用户的具体输入进行分离？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以通过分别创建`SystemPrompt`对象和`UserPrompt`对象来实现。`SystemPrompt`用于定义系统角色和行为指南（如“你是一位经验丰富的Java架构师”），而`UserPrompt`则包含用户的具体请求。最后，将这两个对象放入一个列表中，共同构成一个完整的`Prompt`。</div>
          </div>
          <div class="card-source">来源: 4. 提示词工程实战 / 系统提示与用户提示分离</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
